import os
import re

from pathlib import Path
from collections import namedtuple


def create_dir(file_name: str) -> Path:
    """ 创建文件夹 """
    path = Path(".").absolute() / file_name  # 拼接日志文件夹的路径
    if not Path(path).exists():  # 文件是否存在
        os.makedirs(path)
    return path


def parser_data(data_in: list[dict], columns: list, default="", **kwargs) -> list:
    """
    将list[dict]解析成list[tuple]
    :param data_in:
    :param columns:
    :param default:
    :param kwds:
    :return:
    """
    _tuple = namedtuple('_tuple', columns, defaults=[default] * len(columns))
    return [_tuple(**{key: value for key, value in data.items() if key in columns}, **kwargs) for data in data_in]


def parser_object(data_in: list[dict], columns: list, **kwargs) -> list[dict]:
    # 将list[tuple]解析成list[tuple]
    return [{**{key: value for key, value in data.items() if key in columns}, **kwargs} for data in data_in]


def parser_dict(data_in: list[tuple], columns: list) -> list[dict]:
    # 将list[tuple]解析成list[dict]
    return [dict(zip(columns, row)) for row in data_in]


def singleton(class_):
    instances = {}

    def wrapper(*args, **kwargs):
        if class_ not in instances:
            instances[class_] = class_(*args, **kwargs)
        return instances[class_]

    return wrapper


def name_convert_to_camel(name: str) -> str:
    """下划线转驼峰(小驼峰)"""
    return re.sub(r'(_[a-z])', lambda x: x.group(1)[1].upper(), name)


def name_convert_to_snake(name: str) -> str:
    """驼峰转下划线"""
    if '_' not in name:
        name = re.sub(r'([a-z])([A-Z])', r'\1_\2', name)
    else:
        raise ValueError(f'{name}字符中包含下划线，无法转换')
    return name.lower()


def name_convert(name: str) -> str:
    """驼峰式命名和下划线式命名互转"""
    is_camel_name = True  # 是否为驼峰式命名
    if '_' in name and re.match(r'[a-zA-Z_]+$', name):
        is_camel_name = False
    elif re.match(r'[a-zA-Z]+$', name) is None:
        raise ValueError(f'Value of "name" is invalid: {name}')
    return name_convert_to_snake(name) if is_camel_name else name_convert_to_camel(name)


class DictObject(dict):
    def __init__(self, *args, **kwargs):
        super(DictObject, self).__init__(*args, **kwargs)

    def __getattr__(self, key):
        value = self[key]
        if isinstance(value, dict):
            value = DictObject(value)
        return value


def split_array(arr, size):
    return [arr[i:i + size] for i in range(0, len(arr), size)]


def for_from(l: list[list]):
    return [v for i in l for v in i]


def is_type(val, tp) -> bool:
    """类型判断"""
    return type(val) == tp


def field_mapping(data: list[dict], mapping: dict) -> list[dict]:
    _data = []
    for i in data:
        _temp = {}
        for k, v in mapping.items():
            _temp[k] = i.get(v)
        _data.append(_temp)
    return _data
